package com.usefullc.user.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.usefullc.common.constants.CacheConstants;
import com.usefullc.common.constants.SystemConstant;
import com.usefullc.common.constants.UserConstants;
import com.usefullc.common.enums.RegisterTypeEnum;
import com.usefullc.common.enums.UserGenderEnum;
import com.usefullc.common.enums.UserStatusEnum;
import com.usefullc.common.enums.UserTypeEnum;
import com.usefullc.common.exception.BizException;
import com.usefullc.common.util.*;
import com.usefullc.system.entity.Pager;
import com.usefullc.system.service.AbstractBizService;
import com.usefullc.system.service.component.SystemConfigComponent;
import com.usefullc.user.domain.Employee;
import com.usefullc.user.domain.Role;
import com.usefullc.user.domain.User;
import com.usefullc.user.mapper.UserMapper;
import com.usefullc.user.param.UserEditParam;
import com.usefullc.user.param.UserRegisterParam;
import com.usefullc.user.param.UserRoleParam;
import com.usefullc.user.query.EmployeeQuery;
import com.usefullc.user.query.UserQuery;
import com.usefullc.user.vo.UserVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 用户服务类
 *
 * @author: Sampson
 * @date: 2018-12-19 16:05
 */
@Service
public class UserService extends AbstractBizService<UserMapper,User,UserQuery> {



    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private OuterUserService outerUserService;

    @Autowired
    private EmployeeService employeeService;


    @Autowired
    private SystemConfigComponent systemConfigComponent;

    @Autowired
    private RoleService roleService;

    @Value("${usefullc.api.host}")
    private String apiHost;


    @Override
    protected QueryWrapper<User> getQueryWrapper(UserQuery query) {
        QueryWrapper<User> queryWrapper = super.getQueryWrapper(query);

//        if (StringUtils.isNotEmpty(thisQuery.getBirthdayStart())) {
//            Expression<String> endTimeExpression = criteriaBuilder.function("DATE_FORMAT", String.class,
//                    root.get("birthday"), criteriaBuilder.literal("%m-%d"));
//            predicates.add(criteriaBuilder.greaterThanOrEqualTo(endTimeExpression, thisQuery.getBirthdayStart()));
//        }
//        if (StringUtils.isNotEmpty(thisQuery.getBirthdayEnd())) {
//            Expression<String> endTimeExpression = criteriaBuilder.function("DATE_FORMAT", String.class,
//                    root.get("birthday"), criteriaBuilder.literal("%m-%d"));
//            predicates.add(criteriaBuilder.lessThanOrEqualTo(endTimeExpression, thisQuery.getBirthdayEnd()));
//        }
//        if (StringUtils.isNotEmpty(thisQuery.getGmtCreateStart())) {
//            Expression<String> endTimeExpression = criteriaBuilder.function("DATE_FORMAT", String.class,
//                    root.get("gmtCreate"), criteriaBuilder.literal("%Y-%m-%d"));
//            predicates.add(criteriaBuilder.greaterThanOrEqualTo(endTimeExpression, thisQuery.getGmtCreateStart()));
//        }
//        if (StringUtils.isNotEmpty(thisQuery.getGmtCreateEnd())) {
//            Expression<String> endTimeExpression = criteriaBuilder.function("DATE_FORMAT", String.class,
//                    root.get("gmtCreate"), criteriaBuilder.literal("%Y-%m-%d"));
//            predicates.add(criteriaBuilder.lessThanOrEqualTo(endTimeExpression, thisQuery.getGmtCreateEnd()));
//        }
        return queryWrapper;
    }

    public Pager<UserVo> findVoByPage(UserQuery query){
        Pager<User> pager = this.findByPage(query);
        Pager<UserVo> newPager = new Pager<>(pager);
        List<User> dataList = pager.getDataList();
        List<UserVo> newDataList = new ArrayList<>();
        newPager.setDataList(newDataList);
        for (User user : dataList) {
            UserVo userVo = BeanUtils.beanCopy(user, UserVo.class);
            List<Role> roleList = this.getBaseMapper().findRoleListByUserId(user.getId());
            if (CollectionUtils.isNotEmpty(roleList)) {
                List<Long> roleIds = roleList.stream().map(data -> data.getId()).collect(Collectors.toList());
                userVo.setRoleIds(roleIds);
            }
            newDataList.add(userVo);

            //获取员工
            EmployeeQuery employeeQuery = new EmployeeQuery();
            employeeQuery.setUserId(user.getId());
            Employee employee = employeeService.findOne(employeeQuery);
//            userVo.setEmployee(employee);


        }

        return newPager;
    }


    public User findByTypeAndMobile(Integer type, String areaCode, String mobile) {
        UserQuery userQuery = new UserQuery();
        userQuery.setType(type);
        userQuery.setAreaCode(areaCode);
        userQuery.setMobile(mobile);
        return this.findOne(userQuery);
    }

    public User findByTypeAndEmail(Integer type, String email) {
        UserQuery userQuery = new UserQuery();
        userQuery.setType(type);
        userQuery.setEmail(email);
        return this.findOne(userQuery);

    }

    public User findByTypeAndMobile(Integer type, String mobile) {
        UserQuery userQuery = new UserQuery();
        userQuery.setType(type);
        userQuery.setMobile(mobile);
        return this.findOne(userQuery);
    }

    public User findByTypeAndAccountNo(Integer type, String accountNo) {
        UserQuery userQuery = new UserQuery();
        userQuery.setType(type);
        userQuery.setAccountNo(accountNo);
        return this.findOne(userQuery);

    }


    public boolean checkUserUniqueByAccountNo(Integer type,String accountNo){
        User user = this.findByTypeAndAccountNo(type, accountNo);
        return user == null;
    }

    public boolean checkUserUniqueByMobile(Integer type,String mobile){
        User user = this.findByTypeAndMobile(type, "86",mobile);
        return user == null;
    }

    @Transactional
    public User saveUser(User user) {
        //密码加密
        String newPwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, user.getPwd());
        user.setPwd(newPwd);

        if(StringUtils.isEmpty(user.getNickname())){
            user.setNickname(user.getAccountNo());
        }
        this.save(user);

        if (user.getType() == UserTypeEnum.MEMBER.getCode()) {
            //account
//            UserAccount userAccount = new UserAccount();
//            userAccount.setEnable(YesNoEnum.YES.getCode());
//            userAccount.setUserId(savedUser.getId());
//            userAccount.setAmount(0L);
//            userAccount.setWithdrawAmount(0L);
//            userAccountService.save(userAccount);

        }
        return user;
    }

    public User register(UserRegisterParam userRegisterParam) {
        Integer registerType = userRegisterParam.getRegisterType();
        Integer userType = userRegisterParam.getUserType();
        String areaCode = userRegisterParam.getAreaCode();
        String mobile = userRegisterParam.getMobile();
        String email = userRegisterParam.getEmail();
        String checkCode = userRegisterParam.getCheckCode();
        String pwd = userRegisterParam.getPwd();
        //手机号码是否已被注册
        String accountNo = areaCode + mobile;

        User dbUser = null;
        if (registerType == RegisterTypeEnum.MOBILE.getCode()) {
            dbUser = this.findByTypeAndMobile(userType, areaCode, mobile);
        } else {
            dbUser = this.findByTypeAndEmail(userType, email);
            accountNo = email;
        }
        if (dbUser != null) {
            throw new BizException("手机号码已被注册");
        }

        //短信验证码是否正确
        String checkCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_REGISTER_SMS, userType, accountNo}, "_");
//        String checkCodeKey = this.getCacheKey(CacheConstants.USER_REGISTER_SMS, userType);

        String cacheSmsCode = stringRedisTemplate.opsForValue().get(checkCodeKey);
        if (StringUtils.isEmpty(cacheSmsCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheSmsCode, checkCode)) {
            throw new BizException("验证码错误，请重新输入");
        }

        //密码加密
        String newPwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, pwd.toUpperCase());

        //保存
        User user = new User();
        if(StringUtils.isNotEmpty(userRegisterParam.getAccountNo())){
            accountNo = userRegisterParam.getAccountNo();
        }
        user.setAccountNo(accountNo);  //默认账号，可以修改，必须保证唯一性
        user.setType(userType);
        user.setAreaCode(areaCode);
        user.setMobile(mobile);
        user.setEmail(email);
        user.setNickname(accountNo);
        user.setPwd(newPwd);
        user.setGender(UserGenderEnum.MALE.getCode());
        user.setStatus(UserStatusEnum.PASS.getCode());
        user.setUserName(accountNo);
//        user.setAvatar(+mobile);  //默认图片 TODO

        this.save(user);
        return user;
    }


    public User registerByAccount(UserRegisterParam userRegisterParam) {
//        Integer registerType = userRegisterParam.getRegisterType();
        Integer userType = userRegisterParam.getUserType();
        String areaCode = userRegisterParam.getAreaCode();
        String mobile = userRegisterParam.getMobile();
        String email = userRegisterParam.getEmail();
        String checkCode = userRegisterParam.getCheckCode();
        String pwd = userRegisterParam.getPwd();
        String accountNo = userRegisterParam.getAccountNo();
        String deviceId = userRegisterParam.getDeviceId();

        //账号是否已被注册
        User dbUser = this.findByTypeAndAccountNo(userType,accountNo);
        if (dbUser != null) {
            throw new BizException("该账号已被注册");
        }

        //短信验证码是否正确
        String checkCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_REGISTER_SMS, userType, deviceId}, "_");
//        String checkCodeKey = this.getCacheKey(CacheConstants.USER_REGISTER_SMS, userType);

        String cacheSmsCode = stringRedisTemplate.opsForValue().get(checkCodeKey);
        if (StringUtils.isEmpty(cacheSmsCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheSmsCode, checkCode)) {
            throw new BizException("验证码错误，请重新输入");
        }

        //密码加密
        String newPwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, pwd.toUpperCase());

        //保存
        User user = new User();
        if(StringUtils.isNotEmpty(userRegisterParam.getAccountNo())){
            accountNo = userRegisterParam.getAccountNo();
        }
        user.setAccountNo(accountNo);  //默认账号，可以修改，必须保证唯一性
        user.setType(userType);
        user.setAreaCode(areaCode);
        user.setMobile(mobile);
        user.setEmail(email);
        user.setNickname(accountNo);
        user.setPwd(newPwd);
        user.setGender(UserGenderEnum.MALE.getCode());
        user.setStatus(UserStatusEnum.INIT.getCode());  //等待审核
        user.setUserName(accountNo);
        user.setAvatar(apiHost+"/system/common/res/system/person.png");  //默认图片 TODO

        //默认角色

        this.save(user);
        return user;
    }





    public void saveUser(User user, UserEditParam param){
        user.setType(UserTypeEnum.ADMIN.getCode());

        user.setStatus(UserStatusEnum.PASS.getCode());
        if(user.getId() != null){
            this.update(user);
        }else{
            this.save(user);
        }

        //先删除角色
        this.getBaseMapper().deleteUserRoleByUserId(user.getId());

        List<Long> roleIds = param.getRoleIds();
        if (CollectionUtils.isNotEmpty(roleIds)) {
            List<UserRoleParam> userRoleParams = new ArrayList<>();
            for (Long roleId : roleIds) {
                UserRoleParam userRoleParam = new UserRoleParam();
                userRoleParam.setRoleId(roleId);
                userRoleParam.setUserId(user.getId());
                userRoleParams.add(userRoleParam);
            }
            this.getBaseMapper().insertUserRoleBatch(userRoleParams);
        }
    }

    public UserVo getLoginUser(HttpServletRequest request) {
        String token = request.getHeader(SystemConstant.TOKEN);
        if (StringUtils.isEmpty(token)) {  //针对web 端，从cookie 读取
            token = CookieUtil.getCookieValue(request,SystemConstant.TOKEN);
        }
        if (StringUtils.isEmpty(token)) {
            return null;
        }
        String tokenCacheKey = getUserTokenKey(token);
//        String tokenCacheKey = StringUtils.join(new Object[]{CacheConstants.USER_TOKEN, token}, "_");
        try{
            Object cacheUser = redisTemplate.opsForValue().get(tokenCacheKey);
            if (cacheUser != null) {
                return (UserVo) cacheUser;
            }

        }catch (Exception e){
           logger.error("get login user error",e);
        }
        return null;
    }

    public int updateStatus(Long id,Integer status){
        return this.getBaseMapper().updateStatus(id, status);
    }
    public int updateAllStatus(List<Long> ids,Integer status){
        return this.getBaseMapper().updateAllStatus(ids, status);
    }


    public void updatePwd(Long userId, String oldPwd, String newPwd) {
        User user = this.findById(userId);
        //密码加密
        String encodePwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, oldPwd.toUpperCase());
        if (!StringUtils.equalsIgnoreCase(encodePwd, user.getPwd())) {
            throw new BizException("原始密码错误，请重新输入");
        }
        //密码加密
        String encodeNewPwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, newPwd.toUpperCase());

        //修改
        user.setPwd(encodeNewPwd);
        this.save(user);
    }

    public String resetPwd(List<Long> userIds) {
        String pwd = RandomStringUtils.random(8, true, true);
        String md5Pwd = MD5Utils.MD5Encode(pwd);
        //密码加密
        String encodePwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, md5Pwd);
        this.getBaseMapper().updateAllPwd(userIds,encodePwd);
        return pwd;
    }

    public void updateForgetLoginPwdBySmsCode(Integer userType, String areaCode, String mobile, String smsCode, String newPwd) {
        User user = this.findByTypeAndMobile(userType, areaCode, mobile);
        if (user == null) {
            throw new BizException("该用户没有注册");
        }
        //短信验证码是否正确
        String smsCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_FORGET_PWD_SMS, userType, areaCode + mobile}, "_");
//        String smsCodeKey = this.getCacheKey(CacheConstants.USER_FORGET_PWD_SMS,userType,areaCode+mobile);

        String cacheSmsCode = stringRedisTemplate.opsForValue().get(smsCodeKey);
        if (StringUtils.isEmpty(cacheSmsCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheSmsCode, smsCode)) {
            throw new BizException("验证码错误，请重新输入");
        }
        //密码加密
        String encodePwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, newPwd);

        //修改
        user.setPwd(encodePwd);
        this.save(user);
    }

    public void updateForgetLoginPwdByEmailCode(Integer userType, String email, String smsCode, String newPwd) {
        User user = this.findByTypeAndEmail(userType, email);
        if (user == null) {
            throw new BizException("该用户没有注册");
        }
        //短信验证码是否正确
        String smsCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_FORGET_PWD_SMS, userType, email}, "_");

        String cacheSmsCode = stringRedisTemplate.opsForValue().get(smsCodeKey);
        if (StringUtils.isEmpty(cacheSmsCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheSmsCode, smsCode)) {
            throw new BizException("验证码错误，请重新输入");
        }
        //密码加密
        String encodePwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, newPwd);

        //修改
        user.setPwd(encodePwd);
        this.save(user);
    }

    public void updateMobile(Long userId, String areaCode, String mobile, String smsCode) {
        User user = this.findById(userId);
        if (user == null) {
            throw new BizException("该用户没有注册");
        }
        //短信验证码是否正确
        String smsCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_CHANGE_MOBILE_SMS, user.getType(), areaCode + mobile}, "_");

        String cacheSmsCode = stringRedisTemplate.opsForValue().get(smsCodeKey);
        if (StringUtils.isEmpty(cacheSmsCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheSmsCode, smsCode)) {
            throw new BizException("验证码错误，请重新输入");
        }

        //修改
        user.setMobile(mobile);
        this.save(user);
    }


    public void updateEmail(Long userId, String email, String smsCode) {
        User user = this.findById(userId);
        if (user == null) {
            throw new BizException("该用户没有注册");
        }
        //短信验证码是否正确
        String smsCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_CHANGE_MOBILE_SMS, user.getType(), email}, "_");

        String cacheSmsCode = stringRedisTemplate.opsForValue().get(smsCodeKey);
        if (StringUtils.isEmpty(cacheSmsCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheSmsCode, smsCode)) {
            throw new BizException("验证码错误，请重新输入");
        }

        //修改
        user.setEmail(email);
        this.save(user);
    }

    private String getUserTokenKey(Object key){
        String appEnv = systemConfigComponent.getAppEnv();
        String userIdCacheKey = StringUtils.join(new Object[]{CacheConstants.USER_TOKEN, appEnv,key}, "_");
        return userIdCacheKey;
    }
    private String getCacheKey(String prefix,Object [] args){
        String appEnv = systemConfigComponent.getAppEnv();
        String userIdCacheKey = StringUtils.join(new Object[]{prefix, appEnv,args}, "_");
        return userIdCacheKey;
    }


    public String resetLoginToken(User user) {
        //剔除老的 token user 对象
        String userIdCacheKey = getUserTokenKey(user.getId());
        String oldToken = stringRedisTemplate.opsForValue().get(userIdCacheKey);
        String oldTokenCacheKey = this.getUserTokenKey(oldToken);
//        String oldTokenCacheKey = StringUtils.join(new Object[]{CacheConstants.USER_TOKEN, oldToken}, "_");
        redisTemplate.delete(oldTokenCacheKey);


        //set new token for user 对象
        String newToken = UUID.randomUUID().toString();
        stringRedisTemplate.opsForValue().set(userIdCacheKey, newToken);
//        String oldToken = stringRedisTemplate.opsForValue().get(userIdCacheKey);
//        String tokenCacheKey = StringUtils.join(new Object[]{CacheConstants.USER_TOKEN, newToken}, "_");
        String tokenCacheKey = this.getUserTokenKey(newToken);
        UserVo userVo = BeanUtils.beanCopy(user, UserVo.class);
        List<Role> roleList = this.getBaseMapper().findRoleListByUserId(user.getId());
        if (CollectionUtils.isNotEmpty(roleList)) {
            List<Long> roleIds = roleList.stream().map(data -> data.getId()).collect(Collectors.toList());
            userVo.setRoleIds(roleIds);
        }
        redisTemplate.opsForValue().set(tokenCacheKey, userVo);

        //针对web端，放到cookie 中
        HttpServletResponse response = ResponseUtils.getResponse();
        if(response != null){
//            Cookie sidCookie = new Cookie("sid",uuid);
//            sidCookie.setMaxAge(DateUtil.MONTH_SECONDS);
//            sidCookie.setPath("/");
//            response.addCookie(sidCookie);
            CookieUtil.setCookie(null,response,SystemConstant.TOKEN,newToken);
        }
        return newToken;

    }


    public void clearLoginUser(HttpServletRequest request) {
        String token = request.getHeader(SystemConstant.TOKEN);
        if (StringUtils.isEmpty(token)) {  //针对web 端，从cookie 读取
            token = CookieUtil.getCookieValue(request,SystemConstant.TOKEN);
        }
        if (StringUtils.isEmpty(token)) {
            return;
        }
//        String tokenCacheKey = StringUtils.join(new Object[]{CacheConstants.USER_TOKEN, token}, "_");
        String tokenCacheKey = this.getUserTokenKey(token);
        redisTemplate.delete(tokenCacheKey);
    }

    public User loginByPwd(Integer userType, String accountNo, String pwd) {
        User user = this.findByTypeAndAccountNo(userType, accountNo);
        if (user == null) {
            throw new BizException("账号不存在");
        }
        String newPwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, pwd);
        if (!user.getPwd().equals(newPwd)) {
            throw new BizException("密码不正确");
        }
        return user;
    }

    public User loginByPwd(Integer userType, String accountNo, String pwd, String imgCode, String deviceId) {
        //图形验证码是否正确
        String checkCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_LOGIN_SMS, userType, deviceId}, "_");
        String cacheCheckCode = stringRedisTemplate.opsForValue().get(checkCodeKey);
        if (StringUtils.isEmpty(cacheCheckCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheCheckCode, imgCode)) {
            throw new BizException("验证码错误，请重新输入");
        }
        User user = this.findByTypeAndAccountNo(userType, accountNo);
        if (user == null) {
            throw new BizException("账号不存在");
        }
        if(user.getStatus() == UserStatusEnum.INIT.getCode()){
            throw new BizException("账号待审核",false);
        }
        if(user.getStatus() == UserStatusEnum.NOT_PASS.getCode()){
            throw new BizException("账号不可用",false);
        }
        String newPwd = MD5Utils.MD5EncodeForPwd(UserConstants.PWD_KEY, pwd.toUpperCase());
        if (!user.getPwd().equalsIgnoreCase(newPwd)) {
            throw new BizException("密码不正确");
        }
        return user;
    }



    public User loginBySmsCode(Integer userType, String areaCode, String mobile, String smsCode) {
        User dbUser = this.findByTypeAndMobile(userType, areaCode, mobile);
        if (dbUser == null) {
            throw new BizException("用户不存在");
        }

        //短信验证码是否正确
        String checkCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_LOGIN_SMS, userType, areaCode + mobile}, "_");

        String cacheCheckCode = stringRedisTemplate.opsForValue().get(checkCodeKey);
        if (StringUtils.isEmpty(cacheCheckCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheCheckCode, smsCode)) {
            throw new BizException("验证码错误，请重新输入");
        }
        return dbUser;
    }


    public User loginByEmailCode(Integer userType, String email, String emailCode) {
        User dbUser = this.findByTypeAndEmail(userType, email);
        if (dbUser == null) {
            throw new BizException("用户不存在");
        }

        //短信验证码是否正确
        String checkCodeKey = StringUtils.join(new Object[]{CacheConstants.USER_LOGIN_SMS, userType, email}, "_");

        String cacheCheckCode = stringRedisTemplate.opsForValue().get(checkCodeKey);
        if (StringUtils.isEmpty(cacheCheckCode)) {
            throw new BizException("验证码已失效，请重新获取");
        }

        if (!StringUtils.equals(cacheCheckCode, emailCode)) {
            throw new BizException("验证码错误，请重新输入");
        }
        return dbUser;
    }

    public User loginByWechat(Integer userType, String openId, String areaCode, String mobile, String smsCode, String avatar) {
        return null;
    }




}
